
<!DOCTYPE html>
<!--[if IEMobile 7 ]><html class="no-js iem7"><![endif]-->
<!--[if lt IE 9]><html class="no-js lte-ie8"><![endif]-->
<!--[if (gt IE 8)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js" lang="en"><!--<![endif]-->
<head>
  <meta charset="utf-8">
  <title>iOS同步对象性能对比 - ksnowlv</title>
  <meta name="author" content="律威">

  
  <meta name="description" content="在iOS开发中，支持多种同步方法，我们从耗时角度出发，评估各种同步对象的性能。 1
2
3
4
5
6
7
8 1.@synchronized 2.NSLock 3.NSCondition 4.NSConditionLock 5.NSRecursiveLock 6.pthread_mutex_t &hellip;">
  

  <!-- http://t.co/dKP3o1e -->
  <meta name="HandheldFriendly" content="True">
  <meta name="MobileOptimized" content="320">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  
  <link rel="canonical" href="http://ksnowlv.github.io/blog/2014/09/07/ios-tong-bu-suo-xing-neng-dui-bi">
  <link href="/favicon.png" rel="icon">
  <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css">
  <link href="/atom.xml" rel="alternate" title="ksnowlv" type="application/atom+xml">
  <script src="/javascripts/modernizr-2.0.js"></script>
  <script src="//ajax.useso.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <script>!window.jQuery && document.write(unescape('%3Cscript src="./javascripts/lib/jquery.min.js"%3E%3C/script%3E'))</script>
  <script src="/javascripts/octopress.js" type="text/javascript"></script>
  <!--Fonts from Google"s Web font directory at http://google.com/webfonts -->
<link href="http://fonts.useso.com/css?family=PT+Serif:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
<link href="http://fonts.useso.com/css?family=PT+Sans:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">

  
  <script type="text/javascript">
    var _gaq = _gaq || [];
     _gaq.push(['_setAccount', 'UA-39546615-2']);
    // _gaq.push(['_trackPageview']);

    // (function() {
    //   var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    //   ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    //   var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
    // })();

    _gaq.push(['_trackPageview']);

      (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src='http://droidyue-tools.qiniudn.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
      })();
  </script>


</head>

<body   >
  <header role="banner"><hgroup>
  <h1><a href="/">ksnowlv</a></h1>
  
    <h2>回顾过去,总结以往;立足现在,铭记当下;技术为主,笔记而已.</h2>
  
</hgroup>

</header>
  <nav role="navigation"><ul class="subscription" data-subscription="rss">
  <li><a href="/atom.xml" rel="subscribe-rss" title="subscribe via RSS">RSS</a></li>
  
</ul>
  
<form action="http://google.com/search" method="get">
  <fieldset role="search">
    <input type="hidden" name="q" value="site:ksnowlv.github.io" />
    <input class="search" type="text" name="q" results="0" placeholder="Search"/>
  </fieldset>
</form>
  
<ul class="main-navigation">
  <li><a href="/">博客首页</a></li>
  <li><a href="/blog/archives">文章列表</a></li>
  <!-- <li><a href="/about-me">关于我</a></li>
 -->
</ul>

</nav>
  <div id="main">
    <div id="content">
      <div>
<article class="hentry" role="article">
  
  <header>
    
      <h1 class="entry-title">iOS同步对象性能对比</h1>
    
    
      <p class="meta">
        








  


<time datetime="2014-09-07T10:42:00+08:00" pubdate data-updated="true">Sep 7<span>th</span>, 2014</time>
        
         | <a href="#disqus_thread">Comments</a>
        
      </p>
    
  </header>


<div class="entry-content"><p>在iOS开发中，支持多种同步方法，我们从耗时角度出发，评估各种同步对象的性能。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'> <span class="mf">1.</span><span class="k">@synchronized</span>
</span><span class='line'> <span class="mf">2.</span><span class="n">NSLock</span>
</span><span class='line'> <span class="mf">3.</span><span class="n">NSCondition</span>
</span><span class='line'> <span class="mf">4.</span><span class="n">NSConditionLock</span>
</span><span class='line'> <span class="mf">5.</span><span class="n">NSRecursiveLock</span>
</span><span class='line'> <span class="mf">6.</span><span class="n">pthread_mutex_t</span>
</span><span class='line'> <span class="mf">7.</span><span class="n">OSSpinLock</span>
</span><span class='line'> <span class="mf">8.</span><span class="n">dispatch_barrier_async</span>
</span></code></pre></td></tr></table></div></figure>


<p>示例代码如下：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
<span class='line-number'>88</span>
<span class='line-number'>89</span>
<span class='line-number'>90</span>
<span class='line-number'>91</span>
<span class='line-number'>92</span>
<span class='line-number'>93</span>
<span class='line-number'>94</span>
<span class='line-number'>95</span>
<span class='line-number'>96</span>
<span class='line-number'>97</span>
<span class='line-number'>98</span>
<span class='line-number'>99</span>
<span class='line-number'>100</span>
<span class='line-number'>101</span>
<span class='line-number'>102</span>
<span class='line-number'>103</span>
<span class='line-number'>104</span>
<span class='line-number'>105</span>
<span class='line-number'>106</span>
<span class='line-number'>107</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'>  <span class="k">const</span> <span class="n">NSInteger</span> <span class="n">KRunTimes</span> <span class="o">=</span> <span class="mi">1000</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="kt">double</span> <span class="n">curTime</span><span class="p">,</span> <span class="n">lastTime</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// 1.同步synchronized</span>
</span><span class='line'>  <span class="kt">id</span> <span class="n">obj</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSObject</span> <span class="n">new</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">lastTime</span> <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="k">for</span> <span class="p">(</span><span class="n">NSInteger</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">KRunTimes</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">@synchronized</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="n">curTime</span> <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;@synchronized: %f ms&quot;</span><span class="p">,</span> <span class="p">(</span><span class="n">curTime</span> <span class="o">-</span> <span class="n">lastTime</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// 2.NSLock</span>
</span><span class='line'>  <span class="n">NSLock</span> <span class="o">*</span><span class="n">myLock</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSLock</span> <span class="n">new</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">lastTime</span> <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="k">for</span> <span class="p">(</span><span class="n">NSInteger</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">KRunTimes</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="p">[</span><span class="n">myLock</span> <span class="n">lock</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">myLock</span> <span class="n">unlock</span><span class="p">];</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="n">curTime</span> <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;NSLock: %f ms&quot;</span><span class="p">,</span> <span class="p">(</span><span class="n">curTime</span> <span class="o">-</span> <span class="n">lastTime</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// NSLock IMP</span>
</span><span class='line'>  <span class="k">typedef</span> <span class="nf">void</span> <span class="p">(</span><span class="o">*</span><span class="n">func</span><span class="p">)(</span><span class="kt">id</span><span class="p">,</span> <span class="kt">SEL</span><span class="p">);</span>
</span><span class='line'>  <span class="kt">SEL</span> <span class="n">lockSEL</span> <span class="o">=</span> <span class="k">@selector</span><span class="p">(</span><span class="n">lock</span><span class="p">);</span>
</span><span class='line'>  <span class="kt">SEL</span> <span class="n">unlockSEL</span> <span class="o">=</span> <span class="k">@selector</span><span class="p">(</span><span class="n">unlock</span><span class="p">);</span>
</span><span class='line'>  <span class="n">func</span> <span class="n">lockFunc</span> <span class="o">=</span> <span class="p">(</span><span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="p">)(</span><span class="kt">id</span><span class="p">,</span> <span class="kt">SEL</span><span class="p">))[</span><span class="n">myLock</span> <span class="n">methodForSelector</span> <span class="o">:</span> <span class="n">lockSEL</span><span class="p">];</span>
</span><span class='line'>  <span class="n">func</span> <span class="n">unlockFunc</span> <span class="o">=</span> <span class="p">(</span><span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="p">)(</span><span class="kt">id</span><span class="p">,</span> <span class="kt">SEL</span><span class="p">))[</span><span class="n">myLock</span> <span class="n">methodForSelector</span> <span class="o">:</span> <span class="n">unlockSEL</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">lastTime</span> <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="k">for</span> <span class="p">(</span><span class="n">NSInteger</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">KRunTimes</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">lockFunc</span><span class="p">(</span><span class="n">myLock</span><span class="p">,</span> <span class="n">lockSEL</span><span class="p">);</span>
</span><span class='line'>    <span class="n">unlockFunc</span><span class="p">(</span><span class="n">myLock</span><span class="p">,</span> <span class="n">unlockSEL</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">curTime</span> <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;NSLock + IMP: %f ms&quot;</span><span class="p">,</span> <span class="p">(</span><span class="n">curTime</span> <span class="o">-</span> <span class="n">lastTime</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// 3.NSCondition</span>
</span><span class='line'>  <span class="n">NSCondition</span> <span class="o">*</span><span class="n">condition</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSCondition</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span><span class='line'>  <span class="n">lastTime</span> <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="k">for</span> <span class="p">(</span><span class="n">NSInteger</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">KRunTimes</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="p">[</span><span class="n">condition</span> <span class="n">lock</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">condition</span> <span class="n">unlock</span><span class="p">];</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="n">curTime</span> <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;NSCondition: %f ms&quot;</span><span class="p">,</span> <span class="p">(</span><span class="n">curTime</span> <span class="o">-</span> <span class="n">lastTime</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// 4.NSConditionLock</span>
</span><span class='line'>  <span class="n">NSConditionLock</span> <span class="o">*</span><span class="n">conditionLock</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSConditionLock</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span><span class='line'>  <span class="n">lastTime</span> <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="k">for</span> <span class="p">(</span><span class="n">NSInteger</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">KRunTimes</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="p">[</span><span class="n">conditionLock</span> <span class="n">lock</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">conditionLock</span> <span class="n">unlock</span><span class="p">];</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="n">curTime</span> <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;NSConditionLock: %f ms&quot;</span><span class="p">,</span> <span class="p">(</span><span class="n">curTime</span> <span class="o">-</span> <span class="n">lastTime</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// 5.NSRecursiveLock</span>
</span><span class='line'>  <span class="n">NSRecursiveLock</span> <span class="o">*</span><span class="n">recursiveLock</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSRecursiveLock</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span><span class='line'>  <span class="n">lastTime</span> <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="k">for</span> <span class="p">(</span><span class="n">NSInteger</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">KRunTimes</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="p">[</span><span class="n">recursiveLock</span> <span class="n">lock</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">recursiveLock</span> <span class="n">unlock</span><span class="p">];</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="n">curTime</span> <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;NSRecursiveLock: %f ms&quot;</span><span class="p">,</span> <span class="p">(</span><span class="n">curTime</span> <span class="o">-</span> <span class="n">lastTime</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// 6.pthread_mutex_t</span>
</span><span class='line'>  <span class="n">pthread_mutex_t</span> <span class="n">mutex</span> <span class="o">=</span> <span class="n">PTHREAD_MUTEX_INITIALIZER</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">lastTime</span> <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="k">for</span> <span class="p">(</span><span class="n">NSInteger</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">KRunTimes</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">pthread_mutex_lock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">mutex</span><span class="p">);</span>
</span><span class='line'>    <span class="n">pthread_mutex_unlock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">mutex</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">curTime</span> <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;pthread_mutex: %f ms&quot;</span><span class="p">,</span> <span class="p">(</span><span class="n">curTime</span> <span class="o">-</span> <span class="n">lastTime</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">);</span>
</span><span class='line'>  <span class="n">pthread_mutex_destroy</span><span class="p">(</span><span class="o">&amp;</span><span class="n">mutex</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// 7.OSSpinLock 自旋锁;</span>
</span><span class='line'>  <span class="n">OSSpinLock</span> <span class="n">spinlock</span> <span class="o">=</span> <span class="n">OS_SPINLOCK_INIT</span><span class="p">;</span>
</span><span class='line'>  <span class="n">lastTime</span> <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="k">for</span> <span class="p">(</span><span class="n">NSInteger</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">KRunTimes</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">OSSpinLockLock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">spinlock</span><span class="p">);</span>
</span><span class='line'>    <span class="n">OSSpinLockUnlock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">spinlock</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">curTime</span> <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;OSSpinlock: %f ms&quot;</span><span class="p">,</span> <span class="p">(</span><span class="n">curTime</span> <span class="o">-</span> <span class="n">lastTime</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// 8 dispatch_barrier_async</span>
</span><span class='line'>  <span class="n">dispatch_queue_t</span> <span class="n">queue</span> <span class="o">=</span>
</span><span class='line'>      <span class="n">dispatch_queue_create</span><span class="p">(</span><span class="s">&quot;com.qq.ksnow&quot;</span><span class="p">,</span> <span class="n">DISPATCH_QUEUE_CONCURRENT</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">lastTime</span>   <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="k">for</span> <span class="p">(</span><span class="n">NSInteger</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">KRunTimes</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">dispatch_barrier_async</span><span class="p">(</span><span class="n">queue</span><span class="p">,</span> <span class="o">^</span><span class="p">{});</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="n">curTime</span> <span class="o">=</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>  <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;@dispatch_barrier_async: %f ms&quot;</span><span class="p">,</span> <span class="p">(</span><span class="n">curTime</span> <span class="o">-</span> <span class="n">lastTime</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">);</span>
</span><span class='line'>
</span></code></pre></td></tr></table></div></figure>


<h3>一.模拟器/iOS7/XCode6下性能对比</h3>

<h4>日志情况:</h4>

<pre><code> 2014-09-07 11:26:48.071 LockTest[2713:98107] @synchronized: 232.551038 ms

2014-09-07 11:26:48.173 LockTest[2713:98107] NSLock: 100.879967 ms
2014-09-07 11:26:48.263 LockTest[2713:98107] NSLock + IMP: 89.570999 ms
2014-09-07 11:26:48.353 LockTest[2713:98107] NSCondition: 89.850008 ms
2014-09-07 11:26:48.587 LockTest[2713:98107] NSConditionLock: 233.431995 ms
2014-09-07 11:26:48.677 LockTest[2713:98107] NSRecursiveLock: 89.230001 ms
2014-09-07 11:26:48.740 LockTest[2713:98107] pthread_mutex: 62.326968 ms
2014-09-07 11:26:48.750 LockTest[2713:98107] OSSpinlock: 10.430992 ms
2014-09-07 11:26:49.985 LockTest[2713:98107] dispatch_barrier_async: 1234.429002 ms
</code></pre>

<h4>总结对比</h4>

<p><img src="/images/post/2014-09-07-ios-tong-bu-suo-xing-neng-dui-bi/syn_compared_simulate.png" alt="image" /></p>

<h4>二.iPad Mini2/iOS7/XCode6下性能对比</h4>

<pre><code>2014-09-07 13:32:47.720 LockTest[3494:60b] @synchronized: 499.736011 ms
2014-09-07 13:32:47.948 LockTest[3494:60b] NSLock: 227.194011 ms
2014-09-07 13:32:48.170 LockTest[3494:60b] NSLock + IMP: 221.384048 ms
2014-09-07 13:32:48.393 LockTest[3494:60b] NSCondition: 221.689999 ms
2014-09-07 13:32:49.030 LockTest[3494:60b] NSConditionLock: 636.340976 ms
2014-09-07 13:32:49.260 LockTest[3494:60b] NSRecursiveLock: 229.423046 ms
2014-09-07 13:32:49.431 LockTest[3494:60b] pthread_mutex: 170.615971 ms
2014-09-07 13:32:49.495 LockTest[3494:60b] OSSpinlock: 63.916981 ms
2014-09-07 13:32:49.826 LockTest[3494:60b] dispatch_barrier_async: 329.769015 ms
</code></pre>

<p><img src="/images/post/2014-09-07-ios-tong-bu-suo-xing-neng-dui-bi/syn_compared_ipad_mini2.png" alt="image" /></p>

<h3>总结</h3>

<ul>
<li><p>耗时方面：</p>

<ul>
<li>OSSpinlock耗时最少;</li>
<li>pthread_mutex其次。</li>
<li>NSLock/NSCondition/NSRecursiveLock 耗时接近，220ms上下居中。</li>
<li>NSConditionLock最差，我们常用synchronized倒数第二。</li>
<li>dispatch_barrier_async也许，性能并不像我们想象中的那么好.推测与线程同步调度开销有关。单独block耗时在1ms以下基本上可以忽略不计的。</li>
</ul>
</li>
<li><p>在访问次数比较多的情况下,IMP访问耗时要比消息发送略小。
参看<code>NSLock</code>与<code>NSLock + IMP</code>对比。</p></li>
<li><p>为什么不直接使用<strong>IMP</strong>而使用直接声明函数指针的方式?
XCode6下IMP不能指定参数，报错如下：
<img src="/images/post/2014-09-07-ios-tong-bu-suo-xing-neng-dui-bi/error_overview.png" alt="image" />
如何解决呢？修改LLVM预处理设置即可。详情见<a href="http://ksnowlv.gitcafe.com/blog/2014/09/07/xcode6-too-many-arguments-to-function-call-expected-0-have-2/">XCode6下Too many arguments to function call, expected 0, have 2解决办法</a></p></li>
</ul>


<h3>原因分析</h3>

<h4>1.synchronized</h4>

<pre><code>会创建一个异常捕获handler和一些内部的锁。所以，使用@synchronized替换普通锁的代价是，你付出更多的时间消耗。
</code></pre>

<h4>2.NSConditionLock</h4>

<pre><code>条件锁，与特定的，用户定义的条件有关。可以确保一个线程可以获取满足一定条件的锁。
内部会涉及到信号量机制，一旦一个线程获得锁后，它可以放弃锁并设置相关条件;其它线程竞争该锁。
线程之间的竞争激烈，涉及到条件锁检测，线程间通信。系统调用，上下切换方切换比较频繁。
</code></pre>

<h4>3.OSSpinLock</h4>

<pre><code>自旋锁几乎不进入内核，仅仅是重新加载自旋锁。
如果自旋锁被占用时间是几十，上百纳秒，性能还是挺高的。减少了代价较高的系统调用和一系列上下文言切换。
但是，该锁不是万能的;如果该锁抢占比较多的时候，不要使用该锁。会占用较多cpu,导致耗电较多。
这种情况下使用pthread_mutex虽然耗时多一点，但是，避免了电量过多的消耗。是不错的选择。
</code></pre>

<h4>4.pthread_mutex</h4>

<pre><code>底层的API还是性能比较高啊，在各种同步对象中，性能属于佼佼者。
</code></pre>
</div>


  <footer>
    <p class="meta">
      
  

<span class="byline author vcard">Posted by <span class="fn">律威</span></span>

      








  


<time datetime="2014-09-07T10:42:00+08:00" pubdate data-updated="true">Sep 7<span>th</span>, 2014</time>
      

<span class="categories">
  
    <a class='category' href='/blog/categories/ios-duo-xian-cheng/'>iOS-多线程</a>
  
</span>


      
<DIV >
作者： <A href="/">律威</A> <BR>
出处： <A href="/">http://ksnowlv.gitcafe.com</A> 
<BR>原创文章，版权声明：自由转载-非商用-非衍生-保持署名
<a href= "http://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh"> Creative Commons BY-NC-ND 3.0 </a>。 </DIV>


    </p>
<!--     
      Included file 'post/sharing.html' not found in _includes directory
     -->
    <p class="meta">
      
        <a class="basic-alignment left" href="/blog/2014/09/06/gcd-zhi-jian-ting-wen-jian/" title="Previous Post: GCD之监听文件">&laquo; GCD之监听文件</a>
      
      
        <a class="basic-alignment right" href="/blog/2014/09/07/macxia-nsdistributedlocktong-bu-xing-neng/" title="Next Post: Mac下NSDistributedLock同步性能">Mac下NSDistributedLock同步性能 &raquo;</a>
      
    </p>
  </footer>
</article>

  <section>
    <h1>Comments</h1>
    <div id="disqus_thread" aria-live="polite"><div id="disqus_thread"></div>
<script type="text/javascript">
var disqus_shortname = 'ksnowlv';
(function() {
    var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
    dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
    
</div>
  </section>

</div>

<aside class="sidebar">
  
    <section>
  <h1>关于我</h1>
  <p>律威,QQ:309235009 微信:ksnowlv</p>
  <p>手机单机游戏/手机网游封神online/手机阅读/腾讯iOS地图客户端&实时公交&开放API(地图&街景)/iPad/iPhone淘宝客户端及性能优化</p>
  <p>目前在银客做银客/简理财/...</p>
  <p>能做一点,是一点;不求大成,不求一万年;积少成多,水到渠成!</p>
</section>
<section>
  <h1>最近发布</h1>
  <ul id="recent_posts">
    
      <li class="post">
        <a href="/blog/2017/04/26/android-drawable/">Android drawable</a>
      </li>
    
      <li class="post">
        <a href="/blog/2017/04/22/iOS-xia-shi-yong-ffmpeg/">iOS下使用ffmpeg</a>
      </li>
    
      <li class="post">
        <a href="/blog/2015/08/19/ios-you-xian-hou-tai-ren-wu/">iOS有限后台任务</a>
      </li>
    
      <li class="post">
        <a href="/blog/2015/08/19/android-xia-jie-ya-suo/">Android下gzip数据流解压缩</a>
      </li>
    
      <li class="post">
        <a href="/blog/2015/08/19/facebook-infer-de-shi-yong/">FaceBook-infer的使用</a>
      </li>
    
  </ul>
</section>
<section>
  <h1>分类</h1>
    <ul id="category-list"><li><a href='/blog/categories/android-jie-ya-suo/'>Android-解压缩 (1)</a></li><li><a href='/blog/categories/androidduo-xian-cheng/'>Android多线程 (3)</a></li><li><a href='/blog/categories/androidcha-jian/'>Android插件 (1)</a></li><li><a href='/blog/categories/androidhui-tu-./'>Android绘图。 (1)</a></li><li><a href='/blog/categories/androidwang-luo/'>Android网络 (1)</a></li><li><a href='/blog/categories/git/'>git (6)</a></li><li><a href='/blog/categories/githubbo-ke/'>github博客 (8)</a></li><li><a href='/blog/categories/ios/'>iOS (6)</a></li><li><a href='/blog/categories/ios-block/'>iOS-block (1)</a></li><li><a href='/blog/categories/ios-bug/'>iOS-Bug (2)</a></li><li><a href='/blog/categories/ios-memory/'>iOS-Memory (4)</a></li><li><a href='/blog/categories/ios-push/'>iOS-push (1)</a></li><li><a href='/blog/categories/ios-ui/'>iOS-UI (2)</a></li><li><a href='/blog/categories/ios-you-hua/'>iOS-优化 (1)</a></li><li><a href='/blog/categories/ios-nei-cun/'>iOS-内存 (1)</a></li><li><a href='/blog/categories/ios-ji-chu/'>iOS-基础 (3)</a></li><li><a href='/blog/categories/ios-duo-xian-cheng/'>iOS-多线程 (3)</a></li><li><a href='/blog/categories/ios-cun-chu/'>iOS-存储 (1)</a></li><li><a href='/blog/categories/ios-an-quan/'>iOS-安全 (1)</a></li><li><a href='/blog/categories/ios-wang-luo/'>iOS-网络 (13)</a></li><li><a href='/blog/categories/ios-jie-ya-suo/'>iOS-解压缩 (1)</a></li><li><a href='/blog/categories/ios-she-ji-mo-shi/'>iOS-设计模式 (1)</a></li><li><a href='/blog/categories/ios-diao-shi/'>iOS-调试 (1)</a></li><li><a href='/blog/categories/iosyou-hua/'>iOS优化 (1)</a></li><li><a href='/blog/categories/iosji-chu/'>iOS基础 (2)</a></li><li><a href='/blog/categories/iosyin-pin/'>iOS音频 (1)</a></li><li><a href='/blog/categories/mac/'>Mac (4)</a></li><li><a href='/blog/categories/mac-duo-xian-cheng/'>Mac-多线程 (1)</a></li><li><a href='/blog/categories/nginx/'>nginx (3)</a></li><li><a href='/blog/categories/php/'>php (3)</a></li><li><a href='/blog/categories/python/'>python (12)</a></li><li><a href='/blog/categories/swift/'>swift (11)</a></li><li><a href='/blog/categories/uml/'>UML (8)</a></li><li><a href='/blog/categories/xcode/'>Xcode (11)</a></li><li><a href='/blog/categories/chan-pin-she-ji/'>产品设计 (2)</a></li><li><a href='/blog/categories/gong-ju/'>工具 (2)</a></li><li><a href='/blog/categories/shu-ju-ku/'>数据库 (2)</a></li><li><a href='/blog/categories/sheng-huo-pian-duan/'>生活片段 (10)</a></li><li><a href='/blog/categories/zhi-ye-sheng-ya/'>职业生涯 (7)</a></li><li><a href='/blog/categories/du-shu/'>读书 (2)</a></li></ul>
</section>
<section>
  <h1>外部链接</h1>
    <ul id="外部链接">
    	<li><a href="https://developer.apple.com">苹果开发者中心</a> </li>
    	<li><a href="http://stackoverflow.com/questions/tagged/ios">stackoverflow</a></li>
    	<li><a href="http://ksnowlv.blog.163.com/blog/#m=0">ksnowlv网易博客</a></li>
	</ul>
</section>

  
</aside>


    </div>
  </div>
  <footer role="contentinfo"><p>
  Copyright &copy; 2017 - 律威 -
  <span class="credit">Powered by <a href="http://octopress.org">Octopress</a></span>

  <script type="text/javascript">var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_1253538110'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "v1.cnzz.com/z_stat.php%3Fid%3D1253538110%26online%3D1' type='text/javascript'%3E%3C/script%3E"));</script>

  <script type="text/javascript">
var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://");
document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3F4c1727a94ea20751730e8a556dbdbf82' type='text/javascript'%3E%3C/script%3E"));
</script>

</p>



</footer>
  

<script type="text/javascript">
      var disqus_shortname = 'ksnowlv';
      
        
        // var disqus_developer = 1;
        var disqus_identifier = 'http://ksnowlv.github.io/blog/2014/09/07/ios-tong-bu-suo-xing-neng-dui-bi/';
        var disqus_url = 'http://ksnowlv.github.io/blog/2014/09/07/ios-tong-bu-suo-xing-neng-dui-bi/';
        var disqus_script = 'embed.js';
      
    (function () {
      var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
      dsq.src = 'http://' + disqus_shortname + '.disqus.com/' + disqus_script;
      (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    }());
</script>








</body>
</html>
